﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Controls;
using System.Windows.Forms;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Display;

namespace DIWAGIS.ApplicationLayer.EditorTools
{
    /// <summary>
    /// Summary description for ToolCutPolygon.
    /// </summary>
    [Guid("0d27d669-7a0b-40aa-96e5-767bcbedc58f")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("DIWAGIS.ApplicationLayer.EditorTools.ToolCutPolygon")]
    public sealed class ToolCutPolygon : BaseTool
    {
        #region COM Registration Function(s)
        [ComRegisterFunction()]
        [ComVisible(false)]
        static void RegisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryRegistration(registerType);

            //
            // TODO: Add any COM registration code here
            //
        }

        [ComUnregisterFunction()]
        [ComVisible(false)]
        static void UnregisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryUnregistration(registerType);

            //
            // TODO: Add any COM unregistration code here
            //
        }

        #region ArcGIS Component Category Registrar generated code
        /// <summary>
        /// Required method for ArcGIS Component Category registration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryRegistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            MxCommands.Register(regKey);
            ControlsCommands.Register(regKey);
        }
        /// <summary>
        /// Required method for ArcGIS Component Category unregistration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryUnregistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            MxCommands.Unregister(regKey);
            ControlsCommands.Unregister(regKey);
        }

        #endregion
        #endregion

        private IHookHelper m_hookHelper = null;
        private IMapControl4 m_mapcontrol;
        private IEngineEditLayers m_editLayer;
        private IEngineEditor m_engineEditor;

        public ToolCutPolygon(IEngineEditor engineEditor)
        {
            //
            // TODO: Define values for the public properties
            //
            base.m_category = "Cắt đối tượng"; //localizable text 
            base.m_caption = "Cắt đối tượng";  //localizable text 
            base.m_message = "Cắt đối tượng";  //localizable text
            base.m_toolTip = "Cắt đối tượng";  //localizable text
            base.m_name = "Cắt đối tượng";   //unique id, non-localizable (e.g. "MyCategory_MyTool")

            m_engineEditor = engineEditor;
            try
            {
                //
                // TODO: change resource name if necessary
                //
                string bitmapResourceName = GetType().Name + ".bmp";
                base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
                base.m_cursor = new System.Windows.Forms.Cursor(GetType(), GetType().Name + ".cur");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
            }
        }

        #region Overridden Class Methods

        /// <summary>
        /// Occurs when this tool is created
        /// </summary>
        /// <param name="hook">Instance of the application</param>
        public override void OnCreate(object hook)
        {
            try
            {
                m_hookHelper = new HookHelperClass();
                m_hookHelper.Hook = hook;
                m_engineEditor = new EngineEditorClass();
                m_editLayer = m_engineEditor as IEngineEditLayers;
                if (m_hookHelper.ActiveView == null)
                {
                    m_hookHelper = null;
                }
            }
            catch
            {
                m_hookHelper = null;
            }

            if (m_hookHelper == null)
                base.m_enabled = false;
            else
                base.m_enabled = true;

            // TODO:  Add other initialization code
            if (m_hookHelper.Hook is IMapControl4)
            {
                m_mapcontrol = (IMapControl4)m_hookHelper.Hook;
            }
            else if (m_hookHelper.Hook is IToolbarControl2)
            {
                IToolbarControl2 _toolBar;
                _toolBar = (IToolbarControl2)m_hookHelper.Hook;
                m_mapcontrol = (IMapControl4)_toolBar.Buddy;
            }
        }

        /// <summary>
        /// Occurs when this tool is clicked
        /// </summary>
        public override void OnClick()
        {
            // TODO: Add ToolCutPolygon.OnClick implementation
        }

        public override void OnMouseDown(int Button, int Shift, int X, int Y)
        {
            // TODO:  Add ToolCutPolygon.OnMouseDown implementation
            try
            {
                ESRI.ArcGIS.Display.IScreenDisplay screenDisplay = m_mapcontrol.ActiveView.ScreenDisplay;
                ESRI.ArcGIS.Display.IRubberBand rubberBand = new ESRI.ArcGIS.Display.RubberLineClass();
                ESRI.ArcGIS.Geometry.IGeometry geometry = rubberBand.TrackNew(screenDisplay, null);
                ESRI.ArcGIS.Geometry.IPolyline polyline = (ESRI.ArcGIS.Geometry.IPolyline)geometry;


                ISpatialReference pSpRef;
                pSpRef = m_mapcontrol.Map.SpatialReference;
                polyline.Project(pSpRef);


                ISpatialFilter spatialFilter = new SpatialFilterClass();
                spatialFilter.Geometry = polyline.Envelope as IGeometry;// m_editSketch.Geometry;
                spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;


                //Find the polygon features that cross the sketch.
                IFeatureClass featureClass = m_editLayer.TargetLayer.FeatureClass;
                //MessageBox.Show(featureClass.AliasName);
                if (featureClass.ShapeType != esriGeometryType.esriGeometryPolygon)
                {
                    MessageBox.Show("Công cụ chỉ cắt đối tượng dạng vùng", "Cảnh báo");
                    return;
                }
                IFeatureCursor featureCursor = featureClass.Search(spatialFilter, false);


                IFeature origFeature = featureCursor.NextFeature();
                while (origFeature != null)
                {
                    try
                    {
                        IGeometry pTempGeo;
                        pTempGeo = origFeature.ShapeCopy;
                        pTempGeo.Project(pSpRef);

                        ESRI.ArcGIS.Geometry.ITopologicalOperator4 topologicalOperator4;// = origFeature.Shape as ESRI.ArcGIS.Geometry.ITopologicalOperator4; // Dynamic Cast
                        topologicalOperator4 = pTempGeo as ITopologicalOperator4;
                        if (topologicalOperator4 != null)
                        {
                            ESRI.ArcGIS.Geometry.IGeometryCollection geometryCollection = topologicalOperator4.Cut2(polyline);
                            for (int PartCount = 0; PartCount < geometryCollection.GeometryCount; PartCount++)
                            {
                                IFeature newFeature = featureClass.CreateFeature();
                                newFeature.Shape = geometryCollection.Geometry[PartCount];
                                CopyAttributes(origFeature, newFeature);
                                newFeature.Store();

                                //Flash object
                                IRgbColor clr = new RgbColor();
                                clr.RGB = Color.Red.ToArgb();
                                Class.clsTuongTacBanDo objTuongTacBanDo = new Class.clsTuongTacBanDo();
                                objTuongTacBanDo.FlashGeometry(m_mapcontrol, newFeature.Shape, clr, m_mapcontrol.ActiveView.ScreenDisplay, 2, 400);
                            }
                            origFeature.Delete();
                        }
                        else
                        {
                            MessageBox.Show("Có lỗi trong quá trình cắt đối tượng", "Thông báo lỗi");
                            return;
                        }
                    }
                    catch (COMException comExc)
                    {
                        MessageBox.Show(comExc.Message);
                    }
                    finally
                    {
                        //Continue to work on the next feature if it fails to split the current one.
                        origFeature = featureCursor.NextFeature();
                    }
                }
            }

            catch (COMException comExc)
            {
                  MessageBox.Show(comExc.Message);
                   
            }

        }

        /// <summary>
        /// Sao chép thuộc tính
        /// </summary>
        /// <param name="pSourceFeature"></param>
        /// <param name="pDestinationFeature"></param>
        private void CopyAttributes(IFeature pSourceFeature, IFeature pDestinationFeature)
        {
            IField pField;
            IFields pFields;
            int FieldCount;

            pFields = pSourceFeature.Fields;
            for (FieldCount = 0; FieldCount < pFields.FieldCount; FieldCount++)
            {
                pField = pFields.get_Field(FieldCount);
                if (pField.Editable)
                {
                    if (!(pField.Type == esriFieldType.esriFieldTypeOID) && !(pField.Type == esriFieldType.esriFieldTypeGeometry))
                    {
                        pDestinationFeature.set_Value(FieldCount, pSourceFeature.get_Value(FieldCount));
                    }
                }
            }
        }


        public override void OnMouseMove(int Button, int Shift, int X, int Y)
        {
            // TODO:  Add ToolCutPolygon.OnMouseMove implementation
        }

        public override void OnMouseUp(int Button, int Shift, int X, int Y)
        {
            // TODO:  Add ToolCutPolygon.OnMouseUp implementation
            //ESRI.ArcGIS.Display.IScreenDisplay screenDisplay = m_mapcontrol.ActiveView.ScreenDisplay;

            //ESRI.ArcGIS.Display.IRubberBand rubberBand = new ESRI.ArcGIS.Display.RubberLineClass();
            //ESRI.ArcGIS.Geometry.IGeometry geometry = rubberBand.TrackNew(screenDisplay, null);

            //ESRI.ArcGIS.Geometry.IPolyline polyline = (ESRI.ArcGIS.Geometry.IPolyline)geometry;
        }
        #endregion

        public override bool Enabled
        {
            get
            {
                //check whether Editing 
                if (m_engineEditor.EditState == esriEngineEditState.esriEngineStateNotEditing)
                {
                    return false;
                }
                if ((m_editLayer.TargetLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryPolygon))
                {
                    return false;
                }
                //conditions have been met so enable the tool
                return true;
            }
        }
    }
}
